package com.yungu.swift.api.route.v1.passenger;

import com.alibaba.dubbo.config.annotation.Reference;
import com.yungu.swift.api.base.BaseApi;
import com.yungu.swift.api.facade.PassengerFacade;
import com.yungu.swift.assets.driver.service.DriverService;
import com.yungu.swift.autoconfig.redis.RedisCacheService;
import com.yungu.swift.base.ResponseData;
import com.yungu.swift.constants.CommonConstant;
import com.yungu.swift.constants.OrderConstant;
import com.yungu.swift.lbs.model.DriverPoint;
import com.yungu.swift.lbs.model.vo.DrivingNearestVo;
import com.yungu.swift.lbs.service.DistanceService;
import com.yungu.swift.lbs.service.LocationService;
import com.yungu.swift.order.model.dto.OrderComplainDto;
import com.yungu.swift.order.model.dto.OrderDto;
import com.yungu.swift.order.model.param.ApiOrderListParam;
import com.yungu.swift.order.model.param.ApiOrderNoAnswerCancelParam;
import com.yungu.swift.order.model.param.ApiOrderUuidParam;
import com.yungu.swift.order.model.vo.*;
import com.yungu.swift.order.service.*;
import com.yungu.swift.system.sys.service.SysCompanyService;
import com.yungu.swift.utils.MapUtils;
import com.yungu.swift.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>描述：</p>
 *
 * @author xuzhicheng
 * @Time 2016/12/12
 */
@Controller
@RequestMapping(value = "/api/v1/passenger")
@Api(value = "【乘客】【订单】【公用】乘客订单通用接口", tags = "乘客订单相关操作")
public class OrderApi extends BaseApi {

    @Reference
    private OrderService orderService;
    @Reference
    private OrderDetailService orderDetailService;
    @Reference
    private OrderFareService orderFareService;
    @Reference
    private OrderAlarmService orderAlarmService;
    @Reference
    private OrderComplainService orderComplainService;
    @Reference
    private OrderEvaluateService orderEvaluateService;
    @Reference
    private DriverService driverService;
    @Reference
    private SysCompanyService sysCompanyService;
    @Autowired
    private PassengerFacade passengerFacade;
    @Autowired
    private RedisCacheService redisCacheService;
    @Reference
    private LocationService locationService;
    @Reference
    private DistanceService distanceService;

    @RequestMapping(value = {"/token/order/list"}, method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    @ApiOperation(value = "获取订单列表接口", notes = "")
    public ResponseData<Map<String, Object>> list(
            @ApiParam(name = "appid", value = "APP标识", required = true) @RequestParam String appid,
            @ApiParam(name = "nowPage", value = "当前页", required = false) @RequestParam(required = false) Integer nowPage,
            @ApiParam(name = "businessTypes", value = "需要查询的业务，以逗号分隔", required = false) @RequestParam(required = false) String businessTypes,
            HttpServletRequest request) {

        String uuid = getUserUid(request);
        Map<String, Object> map = MapUtils.build(2);

        List<Integer> businessTypeList = null;
        if (StringUtils.isNotEmpty(businessTypes)) {
            Set<String> toSet = org.springframework.util.StringUtils.commaDelimitedListToSet(businessTypes);
            businessTypeList = toSet.stream().map(str -> Integer.valueOf(str.trim())).collect(Collectors.toList());
        }
        //获取进行中的订单
        ApiOrderListParam orderListParam = new ApiOrderListParam();
        orderListParam.setBusinessTypes(businessTypes);
        orderListParam.setNowPage(nowPage);
        orderListParam.setUserUuid(uuid);
        List<JsonOrderListVo> doingList = orderService.queryOrderDoing(orderListParam).getData();
        //获取已完成的订单
        List<JsonOrderListVo> doneList = orderService.queryOrderDone(orderListParam).getData();

        //只有是第一次请求的（nowPage = 1）才返回正在进行中的订单
        if (1 == nowPage || nowPage == null) {
            map.put("orderDoing", doingList);
        } else {
            map.put("orderDoing", Collections.emptyList());
        }
        map.put("orderDone", doneList);
        //返回总页数给前端
        if (doingList != null && doneList != null) {
            map.put("pageCount", (doingList.size() + doneList.size()) / 10 + 1);
        }
        map.put("nowPage", nowPage);
        return ResponseData.buildSuccessResponse("获取成功", map);
    }

    @RequestMapping(value = {"/token/order/littleWords"}, method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    @ApiOperation(value = "订单捎话接口", notes = "捎话", response = ResponseData.class)
    public ResponseData<Boolean> littleWords(
            @ApiParam(name = "appid", value = "APP标识", required = true) @RequestParam String appid,
            @ApiParam(value = "订单留言", name = "content", required = true) @RequestParam String content,
            @ApiParam(value = "订单id", name = "orderUuid", required = true) @RequestParam String orderUuid) {

        if (!StringUtils.isNotEmpty(orderUuid)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "参数错误");
        }
        return orderDetailService.littleWords(orderUuid, content);
    }

    @RequestMapping(value = {"/token/order/surcharge"}, method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    @ApiOperation(value = "订单空驶费接口", notes = "小费", response = ResponseData.class)
    public ResponseData<Boolean> surcharge(
            @ApiParam(name = "appid", value = "APP标识", required = true) @RequestParam String appid,
            @ApiParam(value = "空驶费", name = "serviceFare", required = true) @RequestParam Double serviceFare,
            @ApiParam(value = "订单id", name = "orderUuid", required = true) @RequestParam String orderUuid) {
        if (!StringUtils.isNotEmpty(orderUuid)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "参数错误");
        }
        return orderFareService.surcharge(orderUuid, serviceFare);
    }


    @RequestMapping(value = {"/token/order/info"}, method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    @ApiOperation(value = "[专车&出租车]订单详情接口", notes = "订单详情", response = ResponseData.class)
    public ResponseData<JsonOrderDetailVo> info(
            @ApiParam(name = "appid", value = "APP标识", required = true) @RequestParam String appid,
            @ApiParam(name = "orderUuid", value = "订单id", required = true) @RequestParam String orderUuid) {
        if (!StringUtils.isNotEmpty(orderUuid)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "参数错误");
        }
        return orderService.getOrderDetail(orderUuid, null);
    }


    @RequestMapping(value = {"/token/order/status"}, method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    @ApiOperation(value = "[出租/专车]首页获取订单状态", notes = "订单状态", response = ResponseData.class)
    public ResponseData<Map<String, Object>> status(
            @ApiParam(name = "appid", value = "APP标识", required = true) @RequestParam String appid,
            @ApiParam(name = "token", value = "token", required = true) @RequestParam("token") String token, HttpServletRequest request) {
        return orderService.getOrderStatus(getUserUid(request), null);
    }

    @RequestMapping(value = {"/token/order/cancel"}, method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    @ApiOperation(value = "[专车&出租车]行程未确定乘客取消订单", notes = "取消订单", response = ResponseData.class)
    public ResponseData<Boolean> cancel(
            @ApiParam(name = "appid", value = "APP标识", required = true) @RequestParam String appid,
            @ApiParam(name = "orderUuid", value = "订单", required = true) @RequestParam String orderUuid,
            HttpServletRequest request) {

        if (!StringUtils.isNotEmpty(orderUuid)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "参数错误");
        }
        ApiOrderNoAnswerCancelParam noAnswerCancelParam = new ApiOrderNoAnswerCancelParam();
        noAnswerCancelParam.setType(1);
        noAnswerCancelParam.setOrderUuid(orderUuid);
        return orderService.noConfirmCancel(noAnswerCancelParam);
    }

    @RequestMapping(value = {"/token/order/autoCancel"}, method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    @ApiOperation(value = "[专车&出租车]行程未确定系统自动取消订单", notes = "取消订单", response = ResponseData.class)
    public ResponseData<Boolean> autoCancel(
            @ApiParam(name = "appid", value = "APP标识", required = true) @RequestParam String appid,
            @ApiParam(name = "orderUuid", value = "订单", required = true) @RequestParam String orderUuid,
            HttpServletRequest request) {

        if (!StringUtils.isNotEmpty(orderUuid)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "参数错误");
        }
        ApiOrderNoAnswerCancelParam noAnswerCancelParam = new ApiOrderNoAnswerCancelParam();
        noAnswerCancelParam.setType(2);
        noAnswerCancelParam.setOrderUuid(orderUuid);
        return orderService.noConfirmCancel(noAnswerCancelParam);
    }

    @RequestMapping(value = {"/token/order/confirmCancel"}, method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    @ApiOperation(value = "行程确定取消订单", notes = "取消订单", response = ResponseData.class)
    public ResponseData<Boolean> confirmCancel(
            @ApiParam(name = "appid", value = "APP标识", required = true) @RequestParam String appid,
            @ApiParam(name = "orderUuid", value = "订单", required = true) @RequestParam String orderUuid,
            @ApiParam(name = "cancelMsg", value = "取消原因") @RequestParam(required = false) String cancelMsg) {
        if (!StringUtils.isNotEmpty(orderUuid)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "参数错误");
        }
        return orderService.pasConfirmCancel(orderUuid, cancelMsg);
    }

    @RequestMapping(value = {"/token/order/cancelDescription"}, method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    @ApiOperation(value = "[专车&出租车]乘客取消订单说明", notes = "取消订单", response = ResponseData.class)
    public ResponseData<Map<String, Object>> isCancel(
            @ApiParam(name = "appid", value = "APP标识", required = true) @RequestParam String appid,
            @ApiParam(name = "orderUuid", value = "订单", required = true) @RequestParam String orderUuid) {
        if (!StringUtils.isNotEmpty(orderUuid)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "参数错误");
        }
        return orderFareService.getPasCancelFare(orderUuid);
    }

    @RequestMapping(value = {"/token/comment/add"}, method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    @ApiOperation(value = "乘客评价司机接口", notes = "保存评价", response = ResponseData.class)
    public ResponseData<String> addComment(
            @ApiParam(name = "appid", value = "APP标识", required = true) @RequestParam String appid,
            @ApiParam(name = "token", value = "token") @RequestParam("token") String token,
            @ApiParam(name = "orderUuid", value = "订单", required = true) @RequestParam String orderUuid,
            @ApiParam(name = "comment", value = "评价内容") @RequestParam(required = false) String comment,
            @ApiParam(name = "commentStr", value = "评价标签,取标签名，多个以“,”隔开") @RequestParam(required = false) String commentStr,
            @ApiParam(name = "score", value = "评分", required = true) @RequestParam Double score,
            HttpServletRequest request) {
        if (StringUtils.isEmpty(orderUuid) || StringUtils.isNull(score)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "参数错误");
        }
        if (StringUtils.isEmpty(getUserUid(request))) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "参数不能为空");
        }
        return orderEvaluateService.addComment(getUserUid(request), orderUuid, comment, commentStr, score);
    }


    @RequestMapping(value = {"/token/complaint/add"}, method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    @ApiOperation(value = "乘客投诉司机接口", notes = "保存投诉", response = ResponseData.class)
    public ResponseData<Boolean> addComplaint(
            @ApiParam(name = "appid", value = "APP标识", required = true) @RequestParam String appid,
            @ApiParam(name = "orderUuid", value = "订单", required = true) @RequestParam String orderUuid,
            @ApiParam(name = "complaintStr", value = "投诉标签,取标签名，多个以“，”隔开") @RequestParam(required = false) String complaintStr,
            @ApiParam(name = "remark", value = "备注") @RequestParam(required = false) String remark,
            @ApiParam(name = "images", value = "投诉图片") @RequestParam(required = false) String images,
            @ApiParam(name = "listenRecording", value = "是否允许调取录音 0不允许 1 允许") @RequestParam(required = false, defaultValue = "0") Integer listenRecording,
            HttpServletRequest request) {
        Map<String, Object> map = MapUtils.build();
        map.put("orderUuid", orderUuid);
        map.put("complainantUuid", getUserUid(request));
        if (orderComplainService.get(map).getData() != null) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "已投诉该司机！");
        }
        OrderDto orderDto = orderService.get(orderUuid).getData();
        if (orderDto == null) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取不到订单信息");
        }
        //新增投诉信息记录
        OrderComplainDto orderComplainDto = new OrderComplainDto();
        orderComplainDto.setUuid(StringUtils.buildUUID());
        orderComplainDto.setOrderUuid(orderUuid);
        orderComplainDto.setComplainantUuid(getUserUid(request));
        orderComplainDto.setRespondentUuid(orderDto.getActualDriverUuid());
        orderComplainDto.setRespondentIdentity(CommonConstant.DRIVER);
        orderComplainDto.setContents(complaintStr);
        orderComplainDto.setRemark(remark);
        orderComplainDto.setImages(images);
        orderComplainDto.setListenRecording(listenRecording);
        orderComplainDto.setStatus(OrderComplainDto.STATUS_PENDING);
        orderComplainDto.setAppid(appid);
        orderComplainDto.setCreateOn(new Date());
        ResponseData<Boolean> responseData = orderComplainService.add(orderComplainDto);
        if (responseData.isSuccess()) {
            responseData.setMsg("投诉成功");
        }
        return responseData;
    }

    @RequestMapping(value = {"/token/alarm/add"}, method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    @ApiOperation(value = "乘客报警接口", notes = "乘客报警", response = ResponseData.class)
    public ResponseData<Boolean> addAlarm(
            @ApiParam(name = "appid", value = "APP标识", required = true) @RequestParam String appid,
            @ApiParam(name = "orderUuid", value = "订单uuid", required = true) @RequestParam String orderUuid,
            @ApiParam(name = "alarmLng", value = "报警经度", required = false) @RequestParam(required = false) String alarmLng,
            @ApiParam(name = "alarmLat", value = "报警纬度", required = false) @RequestParam(required = false) String alarmLat,
            HttpServletRequest request) {

        if (StringUtils.isEmpty(orderUuid)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "参数错误");
        }

        return orderAlarmService.addAlarm(orderUuid, appid, alarmLng, alarmLat);
    }


    @RequestMapping(value = {"/token/order/isComplain"}, method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    @ApiOperation(value = "订单投诉状态查询", notes = "status：1：待处理，2：正在处理，3：已处理", response = ResponseData.class)
    public ResponseData<ApiComplainVo> isComplain(
            @ApiParam(name = "appid", value = "APP标识", required = true) @RequestParam String appid,
            @ApiParam(value = "订单id", name = "orderUuid", required = true) @RequestParam String orderUuid) {
        if (!StringUtils.isNotEmpty(orderUuid)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "参数错误");
        }

        //乘客查看投诉状态，取投诉司机身份的记录
        return orderComplainService.findComplantStatus(orderUuid, CommonConstant.DRIVER);
    }

    @RequestMapping(value = {"/token/order/waitFare"}, method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    @ApiOperation(value = "[专车&出租车]乘客超时等待费用接口", notes = "超时等待金额", response = ResponseData.class)
    public ResponseData<Map<String, Object>> waitFare(
            @ApiParam(name = "appid", value = "APP标识", required = true) @RequestParam String appid,
            @ApiParam(value = "订单id", name = "orderUuid", required = true) @RequestParam String orderUuid) {
        return orderFareService.getBeyondWaitFare(orderUuid);
    }

    @RequestMapping(value = {"/token/order/getDriving"}, method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    @ApiOperation(value = "获取乘客与司机位置规划路径和时间", notes = "规划路径距离时间", response = ResponseData.class)
    public ResponseData getDriver(
            @ApiParam(name = "appid", value = "APP标识", required = true) @RequestParam String appid,
            @ApiParam(name = "orderUuid", value = "订单号", required = true) @RequestParam String orderUuid,
            @ApiParam(name = "drivingType", value = "drivingType：startDriving司机距离起点；endDriving司机距离终点", required = true) @RequestParam String drivingType,
            HttpServletRequest request) {

        String passengerUuid = getUserUid(request);
        ResponseData<JsonOrderDetailVo> responseData = orderService.getOrderDetail(orderUuid, null);
        if (responseData.isSuccess()) {
            JsonOrderDetailVo jsonOrderDetailVo = responseData.getData();
            //根据司机id来获取最新位置
            DriverPoint driverPoint = locationService.findDriverPoint(jsonOrderDetailVo.getDriver().getUuid(), appid).getData();
            if (driverPoint != null) {
                Double driverLng = driverPoint.getCoordinate().getLng();
                Double driverLat = driverPoint.getCoordinate().getLat();
                DecimalFormat df = new DecimalFormat("#.000000");
                ResponseData<DrivingNearestVo> driving;
                String startDriving = "startDriving";
                String endDriving = "endDriving";
                if (startDriving.equals(drivingType)) {
                    driving = distanceService.getDrivingNearest(df.format(driverLng), df.format(driverLat), df.format(Double.parseDouble(jsonOrderDetailVo.getOriginLng())), df.format(Double.parseDouble(jsonOrderDetailVo.getOriginLat())));
                    return driving;
                }
                if (endDriving.equals(drivingType)) {
                    Map<String, Object> map = new HashMap(2);
                    driving = distanceService.getDrivingNearest(df.format(Double.parseDouble(jsonOrderDetailVo.getDestLng())), df.format(Double.parseDouble(jsonOrderDetailVo.getDestLat())), df.format(driverLng), df.format(driverLat));
                    ApiOrderUuidParam orderUuidParam = new ApiOrderUuidParam();
                    orderUuidParam.setOrderUuid(orderUuid);
                    orderUuidParam.setUserUuid(passengerUuid);
                    orderUuidParam.setAppid(appid);
                    ResponseData<OrderEstimateVo> realTimeFare = orderFareService.getRealtimeFare(orderUuidParam);
                    map.put("drivingJson", driving.getData());
                    map.put("realTimeFare", realTimeFare.getData());
                    return ResponseData.buildSuccessResponse("获取司机与终点规划距离", map);
                }
            }
        }
        return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "无法路径规划");
    }

    @RequestMapping(value = {"/token/order/callAgain"})
    @ResponseBody
    @ApiOperation(value = "乘客重新叫车", notes = "乘客重新叫车", response = ResponseData.class)
    public ResponseData callAgain(
            @ApiParam(name = "appid", value = "APP标识", required = true) @RequestParam String appid,
            @ApiParam(value = "订单id", name = "orderUuid", required = true) @RequestParam String orderUuid,
            HttpServletRequest request) {

        String passengerUuid = getUserUid(request);
        if (StringUtils.isEmpty(passengerUuid)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取用户信息错误");
        }
        //先把原有的订单取消掉
        OrderDto newOrderDto = new OrderDto();
        newOrderDto.setUuid(orderUuid);
        orderService.updateOrderStatus(newOrderDto, OrderConstant.ORDER_STATUS_PASSENGER_CANCEL, OrderConstant.ORDER_MAIN_STATUS_CANCEL);
        OrderVo orderVo;
        try {
            orderVo = (OrderVo) redisCacheService.get(orderUuid);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取缓存失败");
        }
        return passengerFacade.createOrder(orderVo);
    }

}
